<!-- 属性面板 -->
<template>
  <div>
    <div v-if="element" class="titleStyle">
      <svg-icon :name="type" class="iconStyle" />
      <div>
        <div>{{ $customTranslate(type) }}</div>
        <div>{{ nodeTitle }}</div>
      </div>
    </div>
    <component
      :is="getComponent"
      v-if="element"
      :element="element"
      :modeling="modeling"
      :moddle="moddle"
    />
  </div>
</template>

<script>
import CommonElement from '../components/bpmn/CommonElement'
import Process from '../components/bpmn/Process'
import StartEvent from '../components/bpmn/events/StartEvent'
import MessageStartEvent from '../components/bpmn/events/message/MessageStartEvent'
import SignalStartEvent from '../components/bpmn/events/signal/SignalStartEvent'
import TimerStartEvent from '../components/bpmn/events/timer/TimerStartEvent'
import ConditionalStartEvent from '../components/bpmn/events/conditional/ConditionalStartEvent'
import MessageEvent from '../components/bpmn/events/message/MessageEvent'
import MessageEndEvent from '../components/bpmn/events/message/MessageEndEvent'
import SignalEvent from '../components/bpmn/events/signal/SignalEvent'
import TimerEvent from '../components/bpmn/events/timer/TimerEvent'
import ConditionalEvent from '../components/bpmn/events/conditional/ConditionalEvent'
import EscalationEvent from '../components/bpmn/events/escalation/EscalationEvent'
import SequenceFlow from '../components/bpmn/SequenceFlow'
import Task from '../components/bpmn/tasks/Task'
import UserTask from '../components/bpmn/tasks/UserTask'
import ServiceTask from '../components/bpmn/tasks/ServiceTask'
import ScriptTask from '../components/bpmn/tasks/ScriptTask'
import BusinessRuleTask from '../components/bpmn/tasks/BusinessRuleTask'
import ReceiveTask from '../components/bpmn/tasks/ReceiveTask'
import CallActivity from '../components/bpmn/subprocess/CallActivity'
import SvgIcon from '../icons/SvgIcon'
import store from '../store'
import { isAny } from 'bpmn-js/lib/util/ModelUtil'
import { getConcreteType } from '../utils'

export default {
  name: 'PropertiesPanel',
  components: {
    CommonElement,
    Process,
    SequenceFlow,
    // events
    StartEvent,
    MessageStartEvent,
    SignalStartEvent,
    TimerStartEvent,
    ConditionalStartEvent,
    MessageEvent,
    MessageEndEvent,
    SignalEvent,
    TimerEvent,
    ConditionalEvent,
    EscalationEvent,
    // tasks
    Task,
    UserTask,
    ServiceTask,
    ScriptTask,
    BusinessRuleTask,
    ReceiveTask,
    // subprocess
    CallActivity,
    SvgIcon
  },
  props: {
    modeler: {
      type: Object,
      required: true
    },
    elementTemplates: {
      type: Array,
      default: () => []
    },
    candidateUsers: {
      type: Array,
      default: null
    },
    candidateGroups: {
      type: Array,
      default: null
    },
    executionListenerClasses: {
      type: Array,
      default: null
    },
    taskListenerClasses: {
      type: Array,
      default: null
    }
  },
  data() {
    return {
      element: null
    }
  },
  computed: {
    getComponent() {
      let type = this.type
      if (type.endsWith('Gateway')) {
        type = 'Gateway'
      }
      switch (type) {
        // https://docs.camunda.org/manual/latest/reference/bpmn20/tasks/send-task/
        case 'SendTask':
          return 'ServiceTask'
        // https://docs.camunda.org/manual/latest/reference/bpmn20/tasks/manual-task/
        case 'ManualTask':
          return 'Task'
        case 'MessageBoundaryEvent':
        case 'MessageIntermediateCatchEvent':
        case 'MessageBoundaryEventNonInterrupting':
          return 'MessageEvent'
        case 'SignalBoundaryEvent':
        case 'SignalIntermediateCatchEvent':
        case 'SignalBoundaryEventNonInterrupting':
          return 'SignalEvent'
        case 'TimerBoundaryEvent':
        case 'TimerIntermediateCatchEvent':
        case 'TimerBoundaryEventNonInterrupting':
          return 'TimerEvent'
        case 'ConditionalBoundaryEvent':
        case 'ConditionalIntermediateCatchEvent':
        case 'ConditionalBoundaryEventNonInterrupting':
          return 'ConditionalEvent'
        case 'EscalationBoundaryEvent':
        case 'EscalationIntermediateCatchEvent':
        case 'EscalationBoundaryEventNonInterrupting':
          return 'EscalationEvent'
        case 'Gateway':
        case 'EndEvent':
        // https://docs.camunda.org/manual/7.17/reference/bpmn20/events/terminate-event/
        case 'TerminateEndEvent':
        case 'BoundaryEvent':
        case 'IntermediateThrowEvent':
          return 'CommonElement'
        default:
          return type
      }
    },
    type() {
      return getConcreteType(this.element)
    },
    modeling() {
      return this.modeler.get('modeling')
    },
    moddle() {
      return this.modeler.get('moddle')
    },
    nodeTitle() {
      const title = store.state.nodeTitle
      return title.length > 20 ? (title.substring(0, 20) + '...') : title
    }
  },
  mounted() {
    this.modeler.on('root.added', e => {
      this.reset(e.element)
    })
    this.modeler.on('element.click', e => {
      this.reset(e.element)
    })
    this.modeler.on('selection.changed', e => {
      if (e['newSelection']?.length) {
        this.reset(e['newSelection'][0])
      }
    })
    this.modeler.get('eventBus').on('commandStack.elements.delete.postExecuted', e => {
      this.reset(e.context.rootElement) // 删除某个元素后，将显示根元素，即Process
    })
  },
  methods: {
    reset(newElement) {
      this.element = null
      this.$nextTick(() => {
        this.element = newElement
        this.postHandle()
      })
    },
    postHandle() {
      store.commit('PUT_TEMPLATE', {
        nodeType: this.element.type,
        templates: this.elementTemplates.filter(t => isAny(this.element, t.appliesTo))
      })
      store.commit('SET_NODE_TITLE',
        this.element.businessObject?.name || this.element.businessObject?.id || this.element.id)
    }
  }
}
</script>
